#include "stdafx.h"
#include "CombatState_Ready.h"
#include "Combat/EvtCombat.h"
#include "Event/EvtImp.h"
#include "Combat/CombatSysImp.h"
#include "Entity/EntityIf.h"
#include "Entity/EntityM.h"
#include "Move/MoveDefinition.h"
#include "Combat/CombatSkill.h"
#include "Combat/CombatDefinition.h"



enum 
{
	ttl_WainForRequest	= 15000,
	ttl_ForNoTarget		= 3000,
};


//
//			For Role
//
//

CombatState_Ready::CombatState_Ready(void)
:m_bCastReqSent(false), m_bHasCast(false)
{
}

CombatState_Ready::~CombatState_Ready()
{
}


void
CombatState_Ready::enter()
{
	//
	//	Make a check for whether there is a cast pending
	m_bHasCast = true;
	//
	//	Make a try to cast next spell
	m_bCastReqSent = false;

	if (!m_wpCombat->hasTargetCE())
	{
		m_nTTL = ttl_ForNoTarget;
	}
}


void
CombatState_Ready::leave()
{
}

bool 
CombatState_Ready::update(int nElapse)
{
	if (m_bHasCast)
	{
		short nStyle;
		if (m_wpCombat->hasSkill(nStyle))
		{
			if (nStyle==CombatSkill::Rd_Melee)
			{
				m_wpCombat->setState(Combat::CBS_Charging);
			}
			else
			{
				m_wpCombat->setState(Combat::CBS_Casting);
			}
		}

		m_bHasCast = false;
	}
	else if (!m_wpCombat->hasTargetCE())
	{
		m_nTTL -= nElapse;
		if (m_nTTL<=0)
		{
			m_wpCombat->setState(Combat::CBS_Peace);
		}
	}
	//
	//	there is a time gap after a new spell cast request is sent until server confirm the current cast
	//
	else if (m_wpCombat->isCalculator())
	{
		if (!m_bCastReqSent)
		{
			//
			//	player can't cast a spell when moving
			//
			if (m_wpEntity->getMoveState()==Move::mst_Moving)
			{
				return true;
			}

			//
			//	ToDo: Need to check the right target with the current spell.
			//
			IEntity* pTarget = m_wpCombat->getTargetCE();
			if (pTarget==NULL)
			{
				m_nTTL = ttl_ForNoTarget;
				return true;
			}

			if (m_wpCombat->TryCastNewSpell())
			{
				m_bCastReqSent = true;
				m_nTTL = ttl_WainForRequest;
			}
		}
		else
		{
			m_nTTL  -= nElapse;
			if (m_nTTL<=0)
			{
				m_bCastReqSent = false;
				LOG_WARN("Failed, spell cast start request expired!\n");
			}
		}
	}

	return true;
}



void 
CombatState_Ready::onEvent(IEvt& evt)
{
	if (evt.getID()==EVT_CastStart)
	{
		m_wpCombat->onEvent_Cast(evt);
		m_bHasCast = true;
	}
	else if (evt.getID()==EVT_CastEnd)
	{
		LOG_ERROR_V("Failed to cast end in : %d !\n", m_wpCombat->getStateName());
	}
	else if (evt.getID()==EVT_CastPrep)
	{
		m_wpCombat->onEvent_CastPrep(evt);
	}
	else if (evt.getID()==EVT_CastResult)
	{
		m_wpCombat->onEvent_CastResult(evt);
	}
	else if (evt.getID()==EVT_TargetSelected)
	{
		m_wpCombat->onEvent_Target(evt);
	}
}


